package com.springboot.demo.modules.websocket;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import com.rabbitmq.client.*;
import com.springboot.demo.utils.Constant;
import com.springboot.demo.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @ServerEndpoint 注解是一个类层次的注解，它的功能主要是将目前的类定义成一个websocket服务器端,
 * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
 */
//@ServerEndpoint("/webSocket")
//@Component
//@RabbitListener(queues = Constant.Rabbitmq.TEST_QUEUE)//监听的队列名称 TestDirectQueue
//@Slf4j
//public class WebSocketServer {
//
//    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
//    private static int onlineCount = 0;
//
//    // 若要实现服务端与单一客户端通信的话，可以使用Map来存放，其中Key可以为用户标识
//    private static ConcurrentHashMap<String, Map<String,WebSocketServer>> webSockets = new ConcurrentHashMap<>();
//
//    //与某个客户端的连接会话，需要通过它来给客户端发送数据
//    private Session session;
//
//    /**
//     * 连接建立成功调用的方法
//     *
//     * @param session
//     * @return: void
//     */
//    @OnOpen
//    public void onOpen(Session session) throws IOException, InterruptedException {
//        this.session = session;
//        String username = session.getUserPrincipal().getName();
//        Map<String,WebSocketServer> map=null;
//        if(webSockets.get(username) == null){
//            map = new HashMap<>();
//            map.put(session.getId(),this);
//            webSockets.put(session.getUserPrincipal().getName(), map);
//        }else{
//            map = webSockets.get(username);
//            map.put(session.getId(),this);
//        }
//        addOnlineCount();           //在线数加1
//        log.info("新连接加入websocket服务器，用户名：" + session.getUserPrincipal().getName() +
//                ",id:" + session.getId() + "当前连接在线数量：" + getOnlineCount());
//    }
//
//    /**
//     * 连接关闭调用的方法
//     *
//     * @return: void
//     */
//    @OnClose
//    public void onClose() {
//        String username = session.getUserPrincipal().getName();
//        Map<String, WebSocketServer> map = webSockets.get(username);
//        if(map.size() == 1){
//            webSockets.remove(username);
//        }else{
//            map.remove(session.getId());
//        }
//        subOnlineCount();           //在线数减1
//        log.info("有一连接关闭，用户名：" + session.getUserPrincipal().getName() + ",id:" + session.getId()
//                + "当前连接在线数量：" + getOnlineCount());
//    }
//
//    /**
//     * 收到客户端消息后调用的方法
//     *
//     * @param message
//     * @return: void
//     */
//    @OnMessage
//    public void onMessage(String message) {
//        log.info("来自客户端的消息:"+message.toString());
//        String username = this.session.getUserPrincipal().getName();
//        WebSocketServer webSocketServer = webSockets.get(username).get(session.getId());
//        try {
//            webSocketServer.sendMessage("服务器收到了来自"+username+"的消息,sessionid:"+session.getId()+
//                            ",时间："+ DateUtils.format(new Date()));
//        } catch (IOException e) {
//            log.error("服务器回复消息出错,用户名:"+username);
//        }
//    }
//
//    /**
//     * 发生错误时调用
//     *
//     * @param error
//     * @return: void
//     */
//    @OnError
//    public void onError(Throwable error) {
//        log.error("连接错误，用户名:"+session.getUserPrincipal().getName()+",id:"+session.getId());
//    }
//
//    /**
//     * 这个方法与上面几个方法不一样。没有用注解，是根据自己需要添加的方法。
//     *
//     * @param message
//     * @return: void
//     */
//    private void sendMessage(String message) throws IOException {
//        synchronized (session) {
//            session.getBasicRemote().sendText(message);
//        }
//    }
//
////    @RabbitHandler
////    public void receiver(Map message) {
////        log.info("来自消息队列的消息："+message);
////        Map<String, WebSocketServer> wu001 = webSockets.get("wu001");
////        if(wu001 == null){
////            System.out.println("wu001 is null");
////        }else{
////            Set<Map.Entry<String, WebSocketServer>> entries = wu001.entrySet();
////            Map.Entry<String, WebSocketServer> first = entries.iterator().next();
////            try {
////                first.getValue().sendMessage("服务器消息:"+message+first.getKey()+
////                        ",时间："+ DateUtils.format(new Date()));
////            } catch (IOException e) {
////                log.error("服务器发送消息出错,用户名：wu001,session:"+first.getKey());
////            }
////        }
////    }
//
//    public static synchronized int getOnlineCount() {
//        return onlineCount;
//    }
//
//    public static synchronized void addOnlineCount() {
//        WebSocketServer.onlineCount++;
//    }
//
//    public static synchronized void subOnlineCount() {
//        WebSocketServer.onlineCount--;
//    }
//
//}